package com.cellulam.framework.core.message;

import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public abstract class AbstractMessage {
    /**
     * 批次号
     */
    private final String batchId;

    /**
     * 发送时间
     */
    private final LocalDateTime sendTime;

    /**
     * 过期时间
     */
    private final LocalDateTime expireTime;

    /**
     * 来源
     */
    private final String source;

    /**
     * 是否异步
     */
    private final Boolean async;

    protected AbstractMessage(Builder builder) {
        this.batchId = builder.batchId;
        this.sendTime = builder.sendTime;
        this.expireTime = builder.expireTime;
        this.source = builder.source;
        this.async = builder.async;
    }

    protected abstract static class Builder<T extends Builder<T>> {

        protected String source;
        protected String batchId;
        protected LocalDateTime sendTime;
        protected LocalDateTime expireTime;
        protected Boolean async;

        /**
         * 来源，不传默认取application name
         * @param source
         * @return
         */
        public T source(String source) {
            this.source = source;
            return (T) this;
        }

        /**
         * 批次号，为空时服务端自动生成
         * @param batchId
         * @return
         */
        public T batchId(String batchId) {
            this.batchId = batchId;
            return (T) this;
        }

        /**
         * 发送时间，不传默认为立即发送
         * @param sendTime
         * @return
         */
        public T sendTime(LocalDateTime sendTime) {
            this.sendTime = sendTime;
            return (T) this;
        }

        /**
         * 短信过期时间，不传默认为2小时(验证码等实时性要求高的需要设短，营销类通知需要长一些
         * @param expireTime
         * @return
         */
        public T expireTime(LocalDateTime expireTime) {
            this.expireTime = expireTime;
            return (T) this;
        }

        /**
         * 是否异步发送，短信通道等级为VERIFICATION时，默认为false，否则为true
         * TODO 除非特殊要求不要设置这个值，未来接入MQ后，此参数会作废，统一为异步发送
         * 除实时性要求特别高的（比如验证码）都应该设置为true
         * @param async
         * @return
         */
        public T async(boolean async) {
            this.async = async;
            return (T) this;
        }

        public abstract AbstractMessage build();
    }
}
